
package engine;

import java.text.DecimalFormat;
import java.util.ArrayList;

/*
 * Vecteur TF.IDF
 */
public class VectorTI {
    private ArrayList<Double> values;
    
    public VectorTI(){
        values = new ArrayList<Double>();
    }
    
    //Constructeur par copie
    public VectorTI(VectorTI v) {
        values = new ArrayList<Double>();

        if (v != null) {
            for(int i=0; i<v.size(); i++){
                this.values.add(v.get(i));
            }
        }
    }
    
    public Double get(Integer index){
        return values.get(index);
    }
    
    public void add(Double val){
        values.add(val);
    }
    
    public Integer size(){
        return values.size();
    }
    
    public void normalize(){
        double norm = 0f;
        for(Double d : values){
            norm += d*d;
        }
        
        if(norm == 0d) return;
        
        norm = Math.sqrt(norm);
        
        for(int i=0; i<values.size(); i++){
            values.set(i, values.get(i)/norm);
        }
    }
    
    //Affichage de tout les composantes
    
    @Override
    public String toString(){
        DecimalFormat twoDecimals = new DecimalFormat("#.##");
        
        String print = "";
        
        for(int i=0; i<values.size(); i++){
            print += twoDecimals.format(values.get(i)) + "; ";
        }
        
        return print;
    }
    
    public String toString(ArrayList<String> voc){
        DecimalFormat twoDecimals = new DecimalFormat("#.##");
        
        String print = "";
        
        for(int i=0; i<values.size(); i++){
            if(values.get(i) != 0f){
                print += voc.get(i) + " : " +  twoDecimals.format(values.get(i)) + "; ";
            }
        }
        
        return print;
    }
    
    //N'affiche que les mots avec un poids supérieur à weightMin
    public String toShortString(ArrayList<String> voc, double weightMin){
        DecimalFormat twoDecimals = new DecimalFormat("#.##");
        
        String print = "";
        
        for(int i=0; i<values.size(); i++){
            if(values.get(i) >= weightMin){
                print += voc.get(i) + " : " +  twoDecimals.format(values.get(i)) + "; ";
            }
        }
        
        return print;
    }
    
    
    /*
     * Voir http://fr.wikipedia.org/wiki/Distance_(math%C3%A9matiques)
     * parametre = 1 -> distance de Manhattan
     * parametre = 2 -> distance Euclidienne
     * parametre = x -> distance de Minkowski
     */
    private static double distanceParametree(VectorTI v1, VectorTI v2, Integer p) {
        double sum = 0d;

        //Parcours de chaque composante
        for (int i=0; i<v1.size(); i++) {

            sum += Math.pow(Math.abs(v1.get(i) - v2.get(i)), p);

        }

        double result = Math.pow(sum, 1d / p);

        return result;
    }

    public static double distanceManhattan(VectorTI v1, VectorTI v2) {
        return distanceParametree(v1, v2, 1);
    }

    public static double distanceEuclidienne(VectorTI v1, VectorTI v2) {
        return distanceParametree(v1, v2, 2);
    }

    public static double distanceMinkowski(VectorTI v1, VectorTI v2, Integer parameter) {
        return distanceParametree(v1, v2, parameter);
    }
}
